/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	SwapChain.h
*
*	Description -	
*
*	Comments	-
*
*	Modification History:
*			Name			   Date					Description
*			MrCodeSushi	-	10/22/2011	-	Creation of this file
**************************************************************************************/
#ifndef _PSX_SWAP_CHAIN_H_
#define _PSX_SWAP_CHAIN_H_

#include "PulseSTD.h"
#include "GraphicsTypes.h"
#include "GraphicsInfrastructure.h"
#include "ShaderResource.h"
#include "ResourcePoolItem.h"
#include "StoragePool.h"

namespace Pulse
{
	struct SwapChainDesc : public BaseResDesc
	{

		SwapChainDesc( void )
		{
			Clear();
		}

		void Set( SIZE_T _width = 0, SIZE_T _height = 0, Rational _refreshRate = Rational(), 
			EGraphicsFormat::Type _format = EGraphicsFormat::UNKNOWN, SampleDesc _sampling = SampleDesc(), BOOL _bWindowed = TRUE, void *_hWnd = PSX_NULL )
		{
			Clear();

			width		= _width;
			height		= _height;
			refreshRate = _refreshRate;
			format		= _format;
			sampleDesc	= _sampling;
			bWindowed	= _bWindowed;
			hWnd		= _hWnd;
		}

		void Clear( void )
		{
			width		= 0;
			height		= 0;
			refreshRate = Rational();
			format		= EGraphicsFormat::UNKNOWN;
			sampleDesc	= SampleDesc();
			bWindowed	= TRUE;
			hWnd		= PSX_NULL;
		}

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::SWAP_CHAIN); }

		SIZE_T					width;
		SIZE_T					height;
		Rational				refreshRate;
		EGraphicsFormat::Type	format;
		SampleDesc				sampleDesc;		
		BOOL					bWindowed;
		void					*hWnd;
	};

	class SwapChain : public IResourcePoolItem
	{
	public:

		virtual ~SwapChain( void );

		// These defines the base interface for all derived resources
		virtual BOOL CreateResource( BaseResDesc *pDesc );
		virtual BOOL DestroyResource( void );
		virtual BOOL LoadResource( void );	
		virtual BOOL UnloadResource( void );

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::SWAP_CHAIN); }

	public:

		Texture2D * GetBackBuffer( void );

		Texture2D * GetBackBufferUnsafe( void );

		void SetDepthBuffer( Texture2D *pDepthBuffer );

		Texture2D * GetDepthBuffer( void );

		Texture2D * GetDepthBufferUnsafe( void );

		EErrorCode::Type Resize( SIZE_T width, SIZE_T height );

		void Present( void );

	private:

		PSX_MakeStoragePoolFriend( SwapChain );

		SwapChain( void );

		EErrorCode::Type ExtractTextureBuffers( void );

		void ReleaseTextureBuffers( void );

		virtual EErrorCode::Type Initialize( void );

		void Cleanup( void );

		SwapChainDesc	m_desc;
		IDXGISwapChain	*m_pSwapChain;
		Texture2D		*m_pSwapChainBuffer;
		Texture2D		*m_pDepthBuffer; // Not being created. Passed over to render path.
		
	};
}

#endif /* _PSX_SWAP_CHAIN_H_ */